package com.shm.leetcode.concurrent;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Semaphore;

/**
 * @author: shm
 * @dateTime: 2020/10/18 21:41
 * @description: 定义H两个信号量，O一个信号量。每个线程每次取一个信号量。
 * 定义一个初始化为3的CyclicBarrier。并且，barrier后加一个runnable的实现，释放H和O的信号量。
 *
 * 作者：luca-zhao
 * 链接：https://leetcode-cn.com/problems/building-h2o/solution/semaphor-cyclicbarrier-zhi-guan-shi-xian-by-luca-z/
 */
class H2O_2 {

    private CyclicBarrier barrier = new CyclicBarrier(3, new Runnable() {
        @Override
        public void run() {
            semaphoreH.release(2);
            semaphoreO.release();
        }
    });

    private Semaphore semaphoreH;
    private Semaphore semaphoreO;

    public H2O_2() {
        semaphoreH = new Semaphore(2);
        semaphoreO = new Semaphore(1);
    }

    public void hydrogen(Runnable releaseHydrogen) throws InterruptedException {
        semaphoreH.acquire();
        // releaseHydrogen.run() outputs "H". Do not change or remove this line.
        releaseHydrogen.run();
        try {
            barrier.await();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }

    public void oxygen(Runnable releaseOxygen) throws InterruptedException {
        semaphoreO.acquire();
        // releaseOxygen.run() outputs "O". Do not change or remove this line.
        releaseOxygen.run();
        try {
            barrier.await();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}